﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using KSAWPFExtensions;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
using KSATouch;

using System.Speech.Synthesis;

using HelixToolkit.Wpf;
using Kinect.Toolbox.Voice; // Excellent libraries from: http://kinecttoolbox.codeplex.com/releases/view/105934

namespace KSAWPFDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : KSAWPFWindow
    {

        SpeechSynthesizer synth = new SpeechSynthesizer();
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
            this.Unloaded += MainWindow_Unloaded;
            this.synth = new SpeechSynthesizer();
            synth.GetInstalledVoices();
            synth.SelectVoice("Microsoft Hazel Desktop");
            synth.SpeakAsync("Greetings");
        }

        void MainWindow_Unloaded(object sender, RoutedEventArgs e)
        {
            this.VoiceCommandRecognized -= MainWindow_VoiceCommandRecognized;
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            string[] commands = new string[] { "Map" };
            try
            {
                this.KsaTouch.AddVoiceCommand(commands);
            }
            catch (Exception exc)
            {
                // kinect most likely not initialized...do not worry about enabling voice
                System.Diagnostics.Debug.WriteLine("Kinect sensor is not initialized! " + exc.Message);
            }
            Home home = new Home();
            SwapInNewControl(home);

            this.VoiceCommandRecognized += MainWindow_VoiceCommandRecognized;

        }

        void MainWindow_VoiceCommandRecognized(string Command)
        {
            // handle voice commands here
        }



        public void SelectChild(string selection)
        {
            UserControl element = null;
            switch (selection.ToUpper())
            {
                case "PHOTOBROWSER":
                    {
                        element = new PhotoBrowser.PhotoBrowser();
                        //synth.SpeakAsync("Loading Photos");
                        break;
                    }
                case "DATAVISUALIZER":
                    {
                        element = new DataVisualizer.DataVisualizer();
                        //synth.SpeakAsync("Displaying Data Visualizer");
                        break;
                    }
                case "HANDWRITING":
                    {
                        element = new InkCanvas.HandwritingSearch();
                        break;
                    }
                case "INKCANVAS":
                    {
                        element = new InkCanvas.KSAInkCanvas();
                        //synth.SpeakAsync("Loading Orientation Demonstration");
                        break;
                    }
                case "CLOSE":
                    {
                        //synth.Speak("Goodbye");
                        Application.Current.Shutdown(0);
                        break;
                    }
                case "THREEDMANIPULATION":
                    {
                        element = new ThreeDManipulation.ThreeDBrowser();
                        //synth.SpeakAsync("Loading 3D Model Browser");
                        break;
                    }
                case "MAPCONTROL":
                    {
                        element = new MapControl();
                        //synth.SpeakAsync("Loading Bing Maps Visualization");
                        break;
                    }
                case "VISUALIZATIONS":
                    {
                        element = new Visualizations.Visualizations();
                        //synth.SpeakAsync("Loading Raw Image Visualization");
                        break;
                    }
                case "HOME":
                    {
                        element = new Home();
                        break;
                    }
                case "HOMEAUTO":
                    {
                        element = new HomeAuto();
                        //synth.SpeakAsync("Loading Home Auotomation Demo");
                        break;
                    }
                default:
                    {
                        // unknown selection
                        MessageBox.Show("Unknown selection chosen: " + selection);
                        break;
                    }
            }
            if (element != null)
            {
                SwapInNewControl(element);
            }
        }

        public void SelectChild(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            if (button != null)
            {
                string selection = button.Tag as string;
                SelectChild(selection);
              
            }
        }

        private void SwapInNewControl(UserControl newControl)
        {
           
            DoubleAnimation fadeout = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(500)));
            DoubleAnimation fadein  = new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(500)));
            fadein.EasingFunction = new CircleEase();
            fadein.BeginTime = TimeSpan.FromMilliseconds(250);

            DoubleAnimation slideOut = new DoubleAnimation(0,-1*this.ActualWidth, new Duration(TimeSpan.FromMilliseconds(250)));
            slideOut.EasingFunction = new CubicEase();

            DoubleAnimation slideIn = new DoubleAnimation(this.ActualWidth,0, new Duration(TimeSpan.FromMilliseconds(250)));
            slideIn.EasingFunction = new PowerEase();

            UserControl oldControl = null;
            TranslateTransform slideOutTransform = new TranslateTransform();
            TranslateTransform slideInTransform = new TranslateTransform(this.ActualWidth,0);

            if (ControlHostGrid.Children.Count > 0)
            {
                oldControl = ControlHostGrid.Children[0] as UserControl;
                oldControl.RenderTransform = slideOutTransform;
                
                // Setup new control
                newControl.RenderTransform = slideInTransform;
                newControl.Opacity = .3;
            }

            if (oldControl == null)
            {
                ControlHostGrid.Children.Add(newControl);
                newControl.Opacity = 0;
                newControl.BeginAnimation(Grid.OpacityProperty, fadein);
                return; // bail, we're not fully initialized
            }
            slideOut.Completed += delegate(object sender2, EventArgs e2)
            {
                slideIn.Completed += delegate(object sender, EventArgs e)
                {
                    if (oldControl != null)
                    {
                        ControlHostGrid.Children.Remove(oldControl);
                        ControlHostGrid.Children.Clear();
                        ControlHostGrid.Children.Add(newControl);
                    }
                };
                slideInTransform.BeginAnimation(TranslateTransform.XProperty, slideIn);
                newControl.BeginAnimation(Grid.OpacityProperty, fadein);
            };
            
            ControlHostGrid.Children.Add(newControl);
            slideOutTransform.BeginAnimation(TranslateTransform.XProperty, slideOut);
            oldControl.BeginAnimation(Grid.OpacityProperty, fadeout);
        }

        /// <summary>
        /// Courtesy of Josh Blake (again) http://nui.joshland.org/2010/04/why-wont-wpf-controls-work-with-touch.html
        /// Highly recommended blog!
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_TouchDown(object sender, TouchEventArgs e)
        {
            FrameworkElement button = sender as FrameworkElement;
         if (button == null)
             return;
                 
         button.CaptureTouch(e.TouchDevice);
      
         e.Handled = true;

        }

        private void button_TouchUp(object sender, TouchEventArgs e)
        {
            FrameworkElement button = sender as FrameworkElement;
            if (button == null)
                return;
            
            button.ReleaseTouchCapture(e.TouchDevice);
     
            e.Handled = true;
        }

        private void Button_PreviewTouchDown(object sender, TouchEventArgs e)
        {
            FrameworkElement button = sender as FrameworkElement;
            if (button == null)
                return;
            ((Button)button).Background = Brushes.Red; // highlight the button for feedback
            button.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
            e.Handled = true;
            ((Button)button).Background = Brushes.Gray; // highlight the button for feedback
        }

        private void Button_PreviewTouchUp_1(object sender, TouchEventArgs e)
        {
            FrameworkElement button = sender as FrameworkElement;
            if (button == null)
                return;

            button.ReleaseTouchCapture(e.TouchDevice);

            e.Handled = true;
        }
    }     
}
